﻿using BunnyEater.Common.Config;
using BunnyEater.Common.Const;
using BunnyEater.Common.Jwt;
using BunnyEater.Domain.SystemManagement;
using BunnyEater.EntityFrameworkCore;
using BunnyEater.Repository;
using BunnyEater.Repository.BaseRepository;
using BunnyEater.Service;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
//using TestManagementSystem.Common.Config;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System.Linq;
using System.Reflection;
using System.Text;

namespace BunnyEater.WebAPI.Extensions
{
    public static class ServiceRegister
    {
        /// <summary>
        /// 注册相关服务
        /// </summary>
        /// <param name="serviceCollection"></param>
        /// <returns></returns>
        public static IServiceCollection ServicesRegister(this IServiceCollection serviceCollection)
        {
            serviceCollection.AddHttpContextAccessor();

            MsSqlDbContextRegister(serviceCollection);
            //jwt认证
            JwtBearerServerRegister(serviceCollection);
            //jwt授权
            serviceCollection.AddAuthorization();
            //注册Swagger
            serviceCollection.AddSwaggerGen();
            //注册swagger配置
            serviceCollection.SwaggerRegister();


            serviceCollection.AddTransient(typeof(IRepository<>), typeof(Repository<>));
            //哈希加密
            serviceCollection.AddSingleton<IPasswordHasher<User>, PasswordHasher<User>>();
            //serviceCollection.AddTransient(typeof(IUnitWork<>), typeof(UnitWork<>));

            Assembly assembly = Assembly.Load(AssemblyConst.PROGRAM_SERCIVE);
            var services = assembly.GetTypes().Where(c => c.IsAssignableTo(typeof(ITransientService))
            && !c.IsAbstract && !c.IsInterface);
            foreach (var service in services)
            {
                var iservice = service.GetInterfaces().FirstOrDefault(c => c.Name != nameof(ITransientService));
                if (iservice != null)
                {
                    serviceCollection.AddTransient(iservice, service);
                }
            }

            //注册跨域
            serviceCollection.CorsRegister();
            return serviceCollection;
        }

        /// <summary>
        /// 注入EFCore
        /// </summary>
        /// <param name="serviceCollection"></param>
        private static void MsSqlDbContextRegister(IServiceCollection serviceCollection)
        {
            serviceCollection.AddDbContext<BunnyEaterContext>(opt =>
            {
                string connectionString = AppSettings.ConnectionString.MSSql;
                opt.UseSqlServer(connectionString, c => c.MigrationsAssembly(AssemblyConst.MIGRATIONSASSEMBLY));
            });
        }

        /// <summary>
        /// jwt认证配置项：注意！：必须放在builder.Build()前 ！
        /// 必须在builder.Services.UseAuthorization()之前
        /// </summary>
        /// <param name="serviceCollection"></param>
        private static void JwtBearerServerRegister(IServiceCollection serviceCollection)
        {
            serviceCollection.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true, // 是否验证Issuer
                    ValidateAudience = true, // 是否验证Audience
                    ValidateLifetime = true, // 是否验证失效时间
                    ValidateIssuerSigningKey = true, // 是否验证SecurityKey
                    ValidIssuer = JwtConfig.JwtInfo.Issuer, // 发行人
                    ValidAudience = JwtConfig.JwtInfo.Audience, // 订阅人
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSecret.GetAccountKey())) // 密钥
                };

                // 从请求中获取token的位置
                options.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        // 从query string中获取token
                        var accessToken = context.Request.Query["access_token"];
                        if (!string.IsNullOrEmpty(accessToken))
                        {
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    }
                };
            });
        }

    }
}
